package android.tusnotas.parser;

import java.util.ArrayList;
import java.util.List;

import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;
import org.htmlcleaner.XPatherException;

import android.tusnotas.beans.Course;
import android.tusnotas.beans.Grade;
import android.tusnotas.beans.Instance;
import android.tusnotas.beans.News;
import android.tusnotas.exception.ProcessingInstancesException;

public class WebCampusParser implements TusNotasParser {

	private List<Instance> instances = new ArrayList<Instance>();
	private TagNode root; 

	/* (non-Javadoc)
	 * @see android.tusnotas.parser.TusNotasParser#initializeHtmlCleaner()
	 */
	@Override
	public HtmlCleaner initializeHtmlCleaner(){

		HtmlCleaner cleaner = new HtmlCleaner();
		CleanerProperties props = cleaner.getProperties();
		props.setAllowHtmlInsideAttributes(Boolean.TRUE);
		props.setAllowMultiWordAttributes(Boolean.TRUE);
		props.setRecognizeUnicodeChars(Boolean.TRUE);
		props.setOmitComments(Boolean.FALSE);
		return cleaner;

	}

	/* (non-Javadoc)
	 * @see android.tusnotas.parser.TusNotasParser#parseHTML(java.lang.String)
	 */
	@Override
	public List<Instance> parseXML(String XML) throws ProcessingInstancesException, XPatherException{

		HtmlCleaner cleaner = initializeHtmlCleaner();
		root = cleaner.clean(XML);
		fillInstances();
		if (this.instances == null){
			throw new ProcessingInstancesException();
		}
		return instances;

	}

	private void fillInstances() throws XPatherException {

		String INSTANCES_XPATH = "//tr[@class]";
		Object[] instancesTable = root.evaluateXPath(INSTANCES_XPATH);
		int courseIndex=0;
		for (int i=0; i<instancesTable.length; i++) {
			TagNode tr = ((TagNode) instancesTable[i]);
			if (tr.getAttributeByName("class").toString().trim().equals("td-ADMdoc-REG")){
				Instance instance = new Instance(tr.getText().toString());
				TagNode courseTagNode = ((TagNode) instancesTable[++i]);
				while (!courseTagNode.getAttributeByName("class").toString().trim().equals("td-ADMdoc-REG")){
					if (courseTagNode.getAttributeByName("class").toString().trim().equals("td-AULA-bkg")){
						fillCourses(courseTagNode, instance, ++courseIndex);
					}
					if (++i >= instancesTable.length){
						break;
					}
					courseTagNode = ((TagNode) instancesTable[i]);
				}
				i--;
				instances.add(instance);
			}
		}
	}

	private void fillCourses(TagNode courseTagNode, Instance instance, int index) throws XPatherException {

		String COURSE_XPATH = "/td//td[1]/a";
		Object[] courses = courseTagNode.evaluateXPath(COURSE_XPATH);

		for (Object object : courses) {

			TagNode tn = (TagNode) object;
//			String[] courseInfo = tn.getText().toString().split("-");
//			Course course = null;
//			if (courseInfo.length>1){
//				course = new Course(courseInfo[0].trim(), courseInfo[1].trim().substring("Aula ".length(),courseInfo[1].trim().length()), -1);
//			}
//			else{
//				course = new Course(courseInfo[0].trim(), "", -1);
//			}
			String coursename = tn.getText().toString();
			Course course = null;
			if (coursename.contains("- Aula ")){
				String[] courseInfo = coursename.split("- Aula ");
				course = new Course(courseInfo[0], courseInfo[1], -1, "", "","");
			} else{
				course = new Course(coursename, "", -1, "", "","");
			}

			fillGrades(course, index);

			fillNews(course, index);

			instance.addCourse(course);
		}
	}

	private void fillGrades(Course course, int index) throws XPatherException {
		String GRADES_XPATH = "//table[@class='tabla-ID2']/../["+index+"]//td";
		Object[] gradeObject = root.evaluateXPath(GRADES_XPATH);
		int size = gradeObject.length;
		for (int i = 0; i < size/2; i++) {

			TagNode tn = (TagNode) gradeObject[i];
			TagNode tn2 = (TagNode) gradeObject[i+size/2];

			Grade grade = new Grade(tn.getText().toString(), tn2.getText().toString(), -1);
			course.addGrade(grade);
		}
	}

	private void fillNews(Course course, int index) throws XPatherException {
		String NEWS_XPATH = "//td[@class='td-AULA-VerNov']/["+index+"]";
		Object[] newsObject = root.evaluateXPath(NEWS_XPATH);
		int size = newsObject.length;

		for (int i=0; i<size; i++){
			TagNode tn = (TagNode) newsObject[i];
			News news = new News(tn.getText().toString(), -1,"","");
			course.addNews(news);
		}

	}

	private void fillFolder(Course course, int index) throws XPatherException {
		String NEWS_XPATH = "//td[@class='td-AULA-VerNov']/["+index+"]";
		Object[] newsObject = root.evaluateXPath(NEWS_XPATH);
		int size = newsObject.length;

		for (int i=0; i<size; i++){
			TagNode tn = (TagNode) newsObject[i];
			News news = new News(tn.getText().toString(), -1,"","");
			course.addNews(news);
		}

	}

	/* (non-Javadoc)
	 * @see android.tusnotas.parser.TusNotasParser#setInstances(java.util.List)
	 */
	@Override
	public void setInstances(List<Instance> instances) {
		this.instances = instances;
	}

	/* (non-Javadoc)
	 * @see android.tusnotas.parser.TusNotasParser#getInstances()
	 */
	@Override
	public List<Instance> getInstances() {
		return instances;
	}
}
